package cn.wolfcode.luowowo.website.controller;

import cn.wolfcode.luowowo.acticle.domain.*;
import cn.wolfcode.luowowo.acticle.query.TravelQuery;
import cn.wolfcode.luowowo.acticle.service.*;
import cn.wolfcode.luowowo.acticle.vo.StrategyStatisVO;
import cn.wolfcode.luowowo.acticle.vo.TravelStatisVO;
import cn.wolfcode.luowowo.cache.service.IDestinationStatisRedisService;
import cn.wolfcode.luowowo.cache.service.IStrategyStatisRedisService;
import cn.wolfcode.luowowo.cache.service.ITravelStatisRedisService;
import cn.wolfcode.luowowo.cache.service.IVerifyCodeRedisService;
import cn.wolfcode.luowowo.comment.domain.SceneryComment;
import cn.wolfcode.luowowo.comment.domain.StrategyComment;
import cn.wolfcode.luowowo.comment.domain.TravelComment;
import cn.wolfcode.luowowo.comment.query.SceneryCommentQuery;
import cn.wolfcode.luowowo.comment.query.StrategyCommentQuery;
import cn.wolfcode.luowowo.comment.query.TravelCommentQuery;
import cn.wolfcode.luowowo.comment.service.ISceneryCommentService;
import cn.wolfcode.luowowo.comment.service.IStrategyCommentService;
import cn.wolfcode.luowowo.comment.service.ITravelCommentService;
import cn.wolfcode.luowowo.common.util.AjaxResult;
import cn.wolfcode.luowowo.member.domain.UserInfo;
import cn.wolfcode.luowowo.member.service.IUserInfoService;
import cn.wolfcode.luowowo.website.annotation.RequireLogin;
import cn.wolfcode.luowowo.website.annotation.UserParam;
import cn.wolfcode.luowowo.website.util.CookieUtil;
import cn.wolfcode.luowowo.website.util.UploadUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;

/**
 * 个人用户
 */
@Controller
@RequestMapping("/mine")
public class UserInfoController {
    @Reference
    private ITravelService travelService;
    @Reference
    private ITravelStatisRedisService travelStatisRedisService;
    @Reference
    private ITravelCommentService travelCommentService;
    @Reference
    private IDestinationService destinationService;
    @Reference
    private IDestinationStatisRedisService destinationStatisRedisService;
    @Reference
    private IStrategyStatisRedisService strategyStatisRedisService;
    @Reference
    private IStrategyDetailService strategyDetailService;
    @Reference
    private IStrategyCommentService strategyCommentService;
    @Reference
    private IUserInfoService userInfoService;
    @Reference
    private IVerifyCodeRedisService verifyCodeRedisService;
    @Reference
    private ISceneryService sceneryService;
    @Reference
    private ISceneryCommentService sceneryCommentService;
    @Value("${file.path}")
    private String filePath;


    /**
     * 我的窝
     */
    @RequestMapping("/home")
    @RequireLogin
    public String home(@UserParam UserInfo userInfo, Model model, TravelQuery qo) {
        //travels
        PageInfo<Travel> pageInfo = travelService.queryMyTravel2(qo, userInfo);
        List<Travel> list = pageInfo.getList();
        for (Travel travel : list) {
            TravelStatisVO vo = travelStatisRedisService.getStatisVo(travel.getId());
            travel.setVo(vo);
        }
        model.addAttribute("travels", list);
        //total
        model.addAttribute("total", pageInfo.getTotal());
        //查询所有该用户的点评内容
        List<SceneryComment> comments = sceneryCommentService.queryByUserId(userInfo.getId());
        if (comments != null && comments.size() != 0) {
            for (SceneryComment comment : comments) {
                Long sceneryId = comment.getSceneryId();
                Scenery scenery = sceneryService.get(sceneryId);
                comment.setSceneryEnglish(scenery.getSubTitle());
            }
            model.addAttribute("comments", comments);
            model.addAttribute("totalComment", comments.size());
        }

        return "mine/home";
    }

    /**
     * 我的收藏
     */
    @RequestMapping("/mytravels")
    @RequireLogin
    public String myTravels(@ModelAttribute("qo") TravelQuery qo, @UserParam UserInfo userInfo, Model model) {
        qo.setPageSize(10);
        //pageInfo
        PageInfo<Travel> pageInfo = travelService.queryMyTravel2(qo, userInfo);
        List<Travel> list = pageInfo.getList();
        int viewnumTotal = 0;
        for (Travel travel : list) {
            TravelStatisVO vo = travelStatisRedisService.getStatisVo(travel.getId());
            travel.setVo(vo);
            viewnumTotal += vo.getViewnum();
        }
        model.addAttribute("pageInfo", pageInfo);
        model.addAttribute("viewnumTotal", viewnumTotal);
        //total
        model.addAttribute("total", pageInfo.getTotal());
        //关联评论数据
        int commentTotal = 0;
        for (Travel travel : list) {
            TravelCommentQuery ctqo = new TravelCommentQuery();
            ctqo.setTravelId(travel.getId());
            ctqo.setPageSize(Integer.MAX_VALUE);
            Page<TravelComment> page = travelCommentService.findByTravelId(ctqo);
            commentTotal += page.getTotalElements();
        }
        model.addAttribute("commentTotal", commentTotal);
        return "mine/mytravelnotes";
    }

    /**
     * 设置
     */
    @RequestMapping("/setting")
    @RequireLogin
    public String setting() {
        return "mine/setting";
    }

    /**
     * 我的收藏
     */
    @RequestMapping("/travelcollection")
    @RequireLogin
    public String travelcollection(@UserParam UserInfo userInfo, Model model) {
        //查询该用户收藏的目的地
        List destIds = destinationStatisRedisService.getDestIds(userInfo.getId());
        if (destIds != null) {
            Collections.reverse(destIds);
            List<Destination> list = new ArrayList<>();
            if (destIds != null) {
                for (Object destId : destIds) {
                    Destination dest = destinationService.get(Long.valueOf((String) destId));
                    //拿到toast,拿到国家名
                    List<Destination> toasts = destinationService.getToastById(Long.valueOf((String) destId));
                    String countryName = toasts.get(0).getName();
                    dest.setCountryName(countryName);
                    list.add(dest);
                }
                if (list.size() != 0) {
                    //dests
                    model.addAttribute("dests", list);
                }
            }
        }
        //查询用户收藏的游记
        List travelIds = travelStatisRedisService.getTravelIds(userInfo.getId());
        if (travelIds != null) {
            Collections.reverse(travelIds);
            TravelCommentQuery qo = null;
            List<Travel> travels = new ArrayList<>();
            for (Object travelId : travelIds) {
                qo = new TravelCommentQuery();
                qo.setTravelId(Long.valueOf((String) travelId));
                Travel travel = travelService.get(Long.valueOf((String) travelId));
                //获取最新回复
                List<TravelComment> content = travelCommentService.findByTravelId(qo).getContent();
                if (content != null && content.size() > 0) {
                    TravelComment comment = content.get(0);
                    travel.setNewComment(comment);
                }
                //获取redis中的数据统计
                TravelStatisVO vo = travelStatisRedisService.getStatisVo(Long.valueOf((String) travelId));
                travel.setVo(vo);
                travels.add(travel);
            }
            //travels
            if (travels.size() != 0) {
                model.addAttribute("travels", travels);
            }
        }
        //查询用户收藏的攻略
        List stragtegyIds = strategyStatisRedisService.getStrategyIds(userInfo.getId());
        if (stragtegyIds != null) {
            Collections.reverse(stragtegyIds);
            StrategyCommentQuery scqo = null;
            List<StrategyDetail> strategys = new ArrayList<>();
            for (Object stragtegyId : stragtegyIds) {
                scqo = new StrategyCommentQuery();
                scqo.setDetailId(Long.valueOf((String) stragtegyId));
                //设置最大条数
                scqo.setPageSize(Integer.MAX_VALUE);
                StrategyDetail strategyDetail = strategyDetailService.get(Long.valueOf((String) stragtegyId));
                Page<StrategyComment> page = strategyCommentService.query(scqo);
                //设置总回复数
                strategyDetail.setCommentTotal(page.getTotalElements());
                //获取最新的回复
                if (page.getContent().size() > 0 && page.getContent() != null) {
                    StrategyComment comment = page.getContent().get(0);
                    strategyDetail.setStrategyComment(comment);
                }
                //获取redis中的数据统计
                StrategyStatisVO vo = strategyStatisRedisService.getStatisVo(Long.valueOf((String) stragtegyId));
                strategyDetail.setVo(vo);
                strategys.add(strategyDetail);
            }
            if (strategys.size() != 0) {
                //strategys
                model.addAttribute("strategys", strategys);
            }
        }
        return "mine/travelcollection";
    }

    /**
     * 修改个人信息
     */
    @RequestMapping("/revise")
    @ResponseBody
    public Object revise(UserInfo userInfo, HttpServletResponse response, HttpSession session) {
        try {
            //修改后并将对象保存到redis中
            String token = userInfoService.update(userInfo);
            //添加cookie
            CookieUtil.addCookie(response, token);
            //共享用户对象
            UserInfo u = userInfoService.getToken(token);
            session.setAttribute("userInfo", u);
            return new AjaxResult();
        } catch (Exception e) {
            e.printStackTrace();
            return new AjaxResult("出现未知错误");
        }
    }

    @RequestMapping("/uploadImg")
    @ResponseBody
    public Object uploadImg(MultipartFile files) {
        String upload = UploadUtil.upload(files, filePath);
        return new AjaxResult(upload);
    }

    /**
     * 跳转修改密码页面
     */
    @RequestMapping("/password")
    public String password(@UserParam UserInfo userInfo, Model model) {
        //创建验证码,并创建到redis缓存中,并返回验证码
        String verifyCode = verifyCodeRedisService.sendVerifyCode(userInfo.getPhone());
        model.addAttribute("code", verifyCode);
        return "mine/revise";
    }

    /**
     * 修改密码
     */
    @RequestMapping("/revisePassword")
    @ResponseBody
    public Object revisePassword(String password, String code, String phone, String rpassword, HttpSession session) {
        userInfoService.revisePassword(password, code, phone, rpassword);
        //消除所有session
        session.invalidate();
        return new AjaxResult();
    }

    /**
     * 发送验证码
     */
    @RequestMapping("/getVerifyCode")
    @ResponseBody
    public Object reEmail(String email, @UserParam UserInfo userInfo, Long type) {
        if ("".equals(email)) {
            return new AjaxResult(false, "不能为空");
        }
        //如果type为1的时候则是发送邮箱验证码,如果是2时表示发送手机验证码
        if (type == 1L) {
            if (email.equals(userInfo.getEmail())) {
                return new AjaxResult(false, "跟之前的一样");
            }
        } else if (type == 2L) {
            if (!email.equals(userInfo.getPhone())) {
                return new AjaxResult(false, "跟原手机不一致");
            }
        } else if (type == 3L) {
            if (email.equals(userInfo.getPhone())) {
                return new AjaxResult(false, "跟之前的一样");
            }
        }
        //创建验证码,并创建到redis缓存中,并返回验证码
        String verifyCode = verifyCodeRedisService.sendVerifyCode(email);
        return new AjaxResult().addData(verifyCode);
    }

    /**
     * 检查邮箱验证码
     */
    @RequestMapping("/checkEmailCode")
    @ResponseBody
    public Object checkEmailCode(Long type, String emailCode, String email, Long id, HttpSession session) {
        UserInfo userInfo = userInfoService.reviseEmail(emailCode, email, id, type);
        //共享用户对象
        session.setAttribute("userInfo", userInfo);
        return new AjaxResult();
    }

    /**
     * userInfo模板
     */
    @RequestMapping("/users")
    public String users(Model model, String keyword) {
        List<UserInfo> list;
        if ("".equals(keyword) || keyword == null) {
            list = userInfoService.list();
        } else {
            list = userInfoService.query(keyword);
        }
        model.addAttribute("users", list);
        return "mine/userTpl";
    }

    /**
     * 我的点评
     */
    @RequestMapping("/review")
    public String review(Model model, @UserParam UserInfo userInfo) {
        //查询所有该用户的点评内容
        List<SceneryComment> comments = sceneryCommentService.queryByUserId(userInfo.getId());
        if (comments != null && comments.size() > 0) {
            for (SceneryComment comment : comments) {
                Long sceneryId = comment.getSceneryId();
                Scenery scenery = sceneryService.get(sceneryId);
                comment.setSceneryEnglish(scenery.getSubTitle());
                comment.setSceneryUrl(scenery.getImgsUrl());
            }
            model.addAttribute("list", comments);
            model.addAttribute("total", comments.size());
        }
        //查询该用户点赞的所有点评
        //先查询到所有评论,再根据遍历每一个评论,看看该用户的id有没有存在评论的点赞者id中
        ArrayList<SceneryComment> thumbUps = new ArrayList<>();
        List<SceneryComment> list = sceneryCommentService.list();
        if (list.size() > 0) {
            for (SceneryComment sceneryComment : list) {
                List<Long> thumbuplist = sceneryComment.getThumbuplist();
                if (thumbuplist.contains(userInfo.getId())) {
                    thumbUps.add(sceneryComment);
                }
            }
            if (comments == null) {
                model.addAttribute("thumbUpTotal", 0);
            } else {
                model.addAttribute("thumbUpTotal", thumbUps.size());
            }
        }
        return "mine/review";
    }

    /**
     * 点评模板
     */
    @RequestMapping("/reviewTpl")
    public String reviewTpl(Model model, Long type, @UserParam UserInfo userInfo) {
        //根据收到的type值来判断是插入哪个模板以及选择哪种排序方式
        //0:空页面, 1:按照创建时间, 2:查询该用户点赞的点评
        if (type == 0) {
            //空页面
            return "mine/reviewTpl1";
        } else if (type == 1) {
            //查询所有该用户的点评内容
            List<SceneryComment> comments = sceneryCommentService.queryByUserId(userInfo.getId());
            if (comments != null && comments.size() > 0) {
                for (SceneryComment comment : comments) {
                    Long sceneryId = comment.getSceneryId();
                    Scenery scenery = sceneryService.get(sceneryId);
                    comment.setSceneryEnglish(scenery.getSubTitle());
                    comment.setSceneryUrl(scenery.getImgsUrl());
                }
                model.addAttribute("list", comments);
                return "mine/reviewTpl2";
            } else {
                return "mine/reviewTpl1";
            }
        } else if (type == 2) {
            //先查询到所有评论,再根据遍历每一个评论,看看该用户的id有没有存在评论的点赞者id中
            ArrayList<SceneryComment> comments = new ArrayList<>();
            List<SceneryComment> list = sceneryCommentService.list();
            if (list.size() > 0 && list != null) {
                for (SceneryComment sceneryComment : list) {
                    List<Long> thumbuplist = sceneryComment.getThumbuplist();
                    if (thumbuplist.contains(userInfo.getId())) {
                        comments.add(sceneryComment);
                    }
                }
                if (comments.size() == 0) {
                    return "mine/reviewTpl1";
                }
                for (SceneryComment comment : comments) {
                    Long sceneryId = comment.getSceneryId();
                    Scenery scenery = sceneryService.get(sceneryId);
                    comment.setSceneryEnglish(scenery.getSubTitle());
                    comment.setSceneryUrl(scenery.getImgsUrl());
                }
                model.addAttribute("list", comments);
                return "mine/reviewTpl2";
            } else {
                return "mine/reviewTpl1";
            }
        }
        return null;
    }
}
